#include <iostream>
#include <vector>
#include <string>
#include <mysql++.h>
#include "stock.h"
#include "printdata.h"

#include "log.h"
#include "message.h"
#include "inOutMsgCenter.h"

using namespace std ;

class DbConnectInfo
{
public:
    string dbName ;
    string server ;
    string user ;
    string password ;
};

DbConnectInfo dbConInfo;

void initDbCon ( )
{
    dbConInfo.dbName   = "mysql_cpp_data" ;
    dbConInfo.server   = "localhost" ;
    dbConInfo.user     = "whq" ;
    dbConInfo.password = "" ;
}

/*void query ( mysqlpp::Connection & con )
{
	string querySQL = "select item,description from stock" ;

	// Retrieve a subset of the stock table's columns, and store
	// the data in a vector of 'stock' SSQLS structures.  See the
	// user manual for the consequences arising from this quiet
	// ability to store a subset of the table in the stock SSQLS.
	mysqlpp::Query query = con.query(querySQL);
	vector<stock> res;
	query.storein(res);

	// Display the items
	cout << "We have:" << endl;
	vector<stock>::iterator it;
	for (it = res.begin(); it != res.end(); ++it) {
		cout << '\t' << it->item;
		if (it->description != mysqlpp::null) {
			cout << " (" << it->description << ")";
		}
		cout << endl;
	}

}

void query_2 ( mysqlpp::Connection & con )
{
    // Retrieve all rows from the stock table and put them in an
    // STL set.  Notice that this works just as well as storing them
    // in a vector, which we did in ssqls1.cpp.  It works because
    // SSQLS objects are less-than comparable.
    mysqlpp::Query query = con.query("select * from stock");
    set<stock> res;
    query.storein(res);

    // Display the result set.  Since it is an STL set and we set up
    // the SSQLS to compare based on the item column, the rows will
    // be sorted by item.
    print_stock_header(res.size());
    set<stock>::iterator it;
    cout.precision(3);
    for (it = res.begin(); it != res.end(); ++it) {
        print_stock_row(it->item.c_str(), it->num, it->weight,
                it->price, it->sdate);
    }

    // Use set's find method to look up a stock item by item name.
    // This also uses the SSQLS comparison setup.
    it = res.find(stock("Hotdog Buns"));
    if (it != res.end()) {
        cout << endl << "Currently " << it->num <<
            " hotdog buns in stock." << endl;
    }
    else {
        cout << endl << "Sorry, no hotdog buns in stock." << endl;
    }
}

void insertRecord ( mysqlpp::Connection & con )
{

    // Create and populate a stock object.  We could also have used
    // the set() member, which takes the same parameters as this
    // constructor.
    stock row("Hot Dogs", 100, 1.5, 1.75,
            mysqlpp::sql_date("1998-09-25"), mysqlpp::null);

    // Form the query to insert the row into the stock table.
    mysqlpp::Query query = con.query();
    query.insert(row);

    // Show the query about to be executed.
    cout << "Query: " << query << endl;

    // Execute the query.  We use execute() because INSERT doesn't
    // return a result set.
    query.execute();

    // Retrieve and print out the new table contents.
    print_stock_table(query);
}

void updateRecord (  mysqlpp::Connection & con )
{
    // Build a query to retrieve the stock item that has Unicode
    // characters encoded in UTF-8 form.
    mysqlpp::Query query = con.query("select * from stock ");
    query << "where item = " << mysqlpp::quote << "Nürnberger Brats";

    // Retrieve the row, throwing an exception if it fails.
    mysqlpp::StoreQueryResult res = query.store();
    if (res.empty()) {
        throw mysqlpp::BadQuery("UTF-8 bratwurst item not found in "
                "table, run resetdb");
    }

    // Because there should only be one row in the result set,
    // there's no point in storing the result in an STL container.
    // We can store the first row directly into a stock structure
    // because one of an SSQLS's constructors takes a Row object.
    stock row = res[0];

    // Create a copy so that the replace query knows what the
    // original values are.
    stock orig_row = row;

    // Change the stock object's item to use only 7-bit ASCII, and
    // to deliberately be wider than normal column widths printed
    // by print_stock_table().
    row.item = "Nuerenberger Bratwurst";

    // Form the query to replace the row in the stock table.
    query.update(orig_row, row);

    // Show the query about to be executed.
    cout << "Query: " << query << endl;

    // Run the query with execute(), since UPDATE doesn't return a
    // result set.
    query.execute();

    // Retrieve and print out the new table contents.
    print_stock_table(query);
}
*/

int main ( int argc, char * argv[] )
{
    initDbCon() ;

    try {
        // Establish the connection to the database server.
        mysqlpp::Connection con(dbConInfo.dbName.c_str(), dbConInfo.server.c_str(), dbConInfo.user.c_str(), dbConInfo.password.c_str() );
        
        InOutMsgCenter msgCenter("BCP-Server2DB", "BCP-DB2Server") ;
        msgCenter.startRxMsg() ;

        /*
           cout<< "----------------query------------------------------------" << endl ;
           query ( con ) ;
           cout<< "----------------query_2------------------------------------" << endl ;
           query_2 ( con ) ;
           cout<< "----------------insertRecord------------------------------------" << endl ;
           insertRecord ( con ) ;
           cout<< "----------------updateRecord------------------------------------" << endl ;
           updateRecord ( con ) ;
           cout<< "----------------------------------------------------" << endl ;
           */
    }
    catch (const mysqlpp::BadQuery& er) {
        // Handle any query errors
        cerr << "Query error: " << er.what() << endl;
        return -1;
    }
    catch (const mysqlpp::BadConversion& er) {
        // Handle bad conversions; e.g. type mismatch populating 'stock'
        cerr << "Conversion error: " << er.what() << endl <<
             "\tretrieved data size: " << er.retrieved <<
             ", actual size: " << er.actual_size << endl;
        return -1;
    }
    catch (const mysqlpp::Exception& er) {
        // Catch-all for any other MySQL++ exceptions
        cerr << "Error: " << er.what() << endl;
        return -1;
    }

    return 0;
}
